﻿#include "uart_interface.h"

UART::UART()
{
    inicpp::IniManager Interface_ini("../config.ini");
    std::string portname = Interface_ini["uart"].toString("port");
    int baudrate = Interface_ini["uart"].toInt("baudrate");
    int rxbufsize = Interface_ini["uart"].toInt("rxbufsize");
    int timeout = Interface_ini["uart"].toInt("timeout");
    m_Csp.init(portname.c_str(), baudrate, itas109::ParityNone, itas109::DataBits8, itas109::StopOne, itas109::FlowNone, timeout);
    m_Csp.setReadIntervalTimeout(10);
    if (m_Csp.open() == false)
    {
        throw std::runtime_error("Open Uart Port Failed");
    }
    else
    {
        std::cout << "Open " << portname.c_str() << " Success" << std::endl;
    }
    m_RxTxThreadRunning.store(true);
    int rxfifosize = Interface_ini["uart"].toInt("rxfifosize");
    int txfifosize = Interface_ini["uart"].toInt("txfifosize");
    m_RxFifo.init(rxfifosize);
    m_TxFifo.init(txfifosize);
}
UART::~UART()
{
    RxTxThreadStop();
    if (m_RxTxThread.joinable())
    {
        m_RxTxThread.join();
    }
    m_Csp.close();
}

void UART::RxTxThreadStart()
{
    m_RxTxThread = std::thread([&]
                               {
		while(m_RxTxThreadRunning.load())
        {
            int rxbuflen = m_Csp.getReadBufferUsedLen();
            if (rxbuflen > 0)
            {
                uint8_t *pdata = new uint8_t[rxbuflen];
                m_Csp.readData(pdata, rxbuflen);
                m_RxFifo.write(pdata, rxbuflen);
                delete[] pdata;
            }
            if (!m_TxFifo.isEmpty())
            {
                int txbuflen = m_TxFifo.count();
                uint8_t *pdata = new uint8_t[txbuflen];
                m_TxFifo.read(pdata, txbuflen);
                m_Csp.writeData(pdata, txbuflen);
                delete[] pdata;
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        } });
    // m_RxTxThread.detach();
}

void UART::RxTxThreadStop()
{
    m_RxTxThreadRunning.store(false);
}

int UART::Receive(uint8_t *data, int count)
{
    return m_RxFifo.read(data, count);
}

int UART::Transmit(uint8_t *data, int count)
{
    return m_TxFifo.write(data, count);
}
